package com.sky.service.admin.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.dto.UserLoginDTO;
import com.sky.exception.BaseException;
import com.sky.mapper.admin.*;
import com.sky.pojo.*;
import com.sky.properties.JwtProperties;
import com.sky.service.admin.CategoryService;
import com.sky.service.admin.UserService;
import com.sky.utils.JwtUtil;
import com.sky.utils.MapUtils;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.UserLoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.analysis.function.Ceil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    //获取openid的路径
    private static final String GET_OPENID_URL="https://api.weixin.qq.com/sns/jscode2session";
    @Value("${sky.wechat.appid}")
    private String appid;
    @Value("${sky.wechat.secret}")
    private String secret;
    private final UserMapper userMapper;
    private final JwtProperties jwtProperties;
    private final MerchantMapper merchantMapper;
    //查询菜品及套餐分类
    private final CategoryMapper categoryMapper;
    //根据id查询caipin
    private final DishMapper dishMapper;
    //根据id查询口味
    private final FlavorsMapper flavorsMapper;
    //根据id查询套餐
    private final SetmealMapper setmealMapper;

    @Override
    public UserLoginVO toAppLogin(UserLoginDTO dto) {
        //根据code获取openid
        String openid = getOpenid(dto.getCode());
        //判断openid是否存在
        if(!StringUtils.hasText(openid)){
            log.info("没有该用户：{}",openid);
        }
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getOpenid, openid));
        //存入用户表
        if(user==null){
            User newUser = new User();
            newUser.setName("过过过");
            newUser.setPhone(dto.getTelephone());
            newUser.setOpenid(openid);
            newUser.setCreateTime(LocalDateTime.now());

            super.save(newUser);
            user=newUser;
        }
        //生成token返回给前端
        Map<String,Object> map = new HashMap<>();
        Long id = user.getId();
        map.put("id",id);
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), map);
        log.info("生成的token信息是：{}",token);

        //商家信息查询,哪里来的id
        //题目中说了固定查询id为1的商家
        Merchant merchantOne = merchantMapper.selectOne(Wrappers.<Merchant>lambdaQuery().eq(Merchant::getId, 1));
        if (merchantOne==null){
            log.info("没有此商家");
            throw new BaseException("没有这家店");
        }
        //计算配送费用
        String shopAddress = merchantOne.getShopAddress();
        String localtionShop = MapUtils.addressToLnglat(shopAddress);
        double distance = MapUtils.calculateDistance(dto.getLocation(), localtionShop);
        //计费规则：首公里3元，后续每公里1元，不足一公里按照1公里计算
        //距离向上取整
        double distanceCeil = Math.ceil(distance);
        double fee=3;
        if (distanceCeil>1){
            fee+=(distanceCeil-1);
        }
        //封装数据返回前端
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setOpenid(openid);
        userLoginVO.setToken(token);
        userLoginVO.setShopName(merchantOne.getShopName());
        userLoginVO.setShopAddress(merchantOne.getShopAddress());
        userLoginVO.setShopTelephone(merchantOne.getShopTelephone());
        userLoginVO.setShopId(merchantOne.getId());
        userLoginVO.setDeliveryFee(BigDecimal.valueOf(fee));
        return userLoginVO;


    }

    /*
    * 获取openid
    * */
    private String getOpenid(String code){
        Map<String,Object> map =new HashMap<>();
        map.put("appid",appid);
        map.put("secret",secret);
        map.put("js_code",code);
        map.put("grant_type","authorization_code");
        //返回一个字符串
        String responce = HttpUtil.get(GET_OPENID_URL, map);
        log.info("打印API响应信息：{}",responce);
        //解析字符串
        JSONObject parseObj = JSONUtil.parseObj(responce);
        String openid = parseObj.getStr("openid");

        return openid;
    }

    /*
     * 查询菜品即套餐分类
     * */
    @Override
    public List<Category> selectCategory(Integer type) {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getType,type);
        List<Category> categories = categoryMapper.selectList(wrapper);
        return categories;
    }

    /*
     * 根据分类id查询菜品
     * */
    @Override
    public List<DishVO> selectDishByCategoryId(Long id) {
        List<DishVO> dishVOList =new ArrayList<>();
        List<Dish> dishs = dishMapper.selectList(Wrappers.<Dish>lambdaQuery().eq(Dish::getCategoryId, id));
        for (Dish dish : dishs) {
            DishVO dishVO = new DishVO();
            //一整个集合粘贴不过去，就一个一个的粘贴过去
            BeanUtils.copyProperties(dish,dishVO);
            dishVOList.add(dishVO);
        }
        return dishVOList;
    }

    /*
     * 根据菜品分类id查询套餐
     * */
    @Override
    public List<Setmeal> selectSetmealByCategoryId(Long id) {
        List<Setmeal> setmeals = setmealMapper.selectList(Wrappers.<Setmeal>lambdaQuery().eq(Setmeal::getCategoryId, id));
        return setmeals;
    }

    /*
     * 根据套餐id查询包含的菜品
     * */
    @Override
    public List<DishItemVO> selectDishBySetmealId(Long id) {
        List<DishItemVO> dishItemVOList=new ArrayList<>();
        Setmeal setmeal = setmealMapper.selectOne(Wrappers.<Setmeal>lambdaQuery().eq(Setmeal::getId, id));
        Long categoryId = setmeal.getCategoryId();
        Dish dish = dishMapper.selectOne(Wrappers.<Dish>lambdaQuery().eq(Dish::getCategoryId, categoryId));
        DishItemVO dishItemVO = new DishItemVO();
        dishItemVO.setName(dish.getName());
        //todo 分数写成固定的了
        dishItemVO.setCopies(1);
        dishItemVO.setImage(dish.getImage());
        dishItemVO.setDescription(dish.getDescription());
        dishItemVOList.add(dishItemVO);
        return dishItemVOList;
    }

}
